import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Computer
extends LMCElement
implements RunUpdater {

    private Runner runner;
    private Action loadAction;
    private Action stepAction;
    private Action runAction;

    protected Action[] createToolBarActions() {
	loadAction = new AbstractAction() {
	    public void actionPerformed(ActionEvent e) {
		LMC.getMemory().load();
		LMC.getCPU().initialize();
		LMC.getIO().clear();
		update();
		setRunEnabled(true);
	    }
	};
	runner = new Runner(LMC.getCPU(), this);
	loadAction.setEnabled(false);
	loadAction.putValue(Action.NAME, "Load");
	loadAction.putValue(Action.SHORT_DESCRIPTION,
		"Load the assembled program into the computer");
	stepAction = runner.getStepAction();
	stepAction.putValue(Action.SHORT_DESCRIPTION,
		"Run just one instruction");
	runAction = runner.getRunAction();
	runAction.putValue(Action.SHORT_DESCRIPTION,
		"Run program to completion");
	setRunEnabled(false);
	return new Action[] {
	    loadAction,
	    stepAction,
	    runAction
	};
    }

    protected JComponent createVisual() {
	JPanel mainPanel = new JPanel(new BorderLayout());
	mainPanel.add(LMC.getIO().createVisual(), BorderLayout.WEST);
	mainPanel.add(LMC.getCPU().createVisual(), BorderLayout.CENTER);
	mainPanel.add(LMC.getMemory().createVisual(), BorderLayout.EAST);
	return mainPanel;
    }

    public Computer() {
	super();
	frame.setTitle("LMC Computer");
	Dimension eDim = LMC.getEditor().getFrame().getSize();
	Dimension aDim = LMC.getAssembler().getFrame().getSize();
	frame.setLocation(eDim.width + 10, aDim.height + 10);
	frame.setIconifiable(true);
	frame.setResizable(true);
    }

    public void update() {
	LMC.getCPU().updateDisplay();
	LMC.getIO().updateDisplay();
	LMC.getMemory().updateDisplay();
    }

    public void setLoadEnabled(boolean le) {
	loadAction.setEnabled(le);
    }

    public void setRunEnabled(boolean re) {
	runner.setEnabled(re);
    }

}

